﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using Catel.Data;
using DevExpress.Xpo;
using DevExpress.Xpo.DB;

namespace LprMiddleWare
{
    /// <summary>
    /// Settings Data object class which fully supports serialization, property changed notifications,
    /// backwards compatibility and error checking.
    /// </summary>
#if !SILVERLIGHT
    [Serializable]
#endif
    public class Settings : SavableModelBase<Settings>
    {
        private const string ConfigFileName = "config.xml";
        private static Settings _instance;

        #region Variables
        #endregion

        #region Constructor & destructor
        /// <summary>
        /// Initializes a new object from scratch.
        /// </summary>
        public Settings()
        {

        }

#if !SILVERLIGHT
        /// <summary>
        /// Initializes a new object based on <see cref="SerializationInfo"/>.
        /// </summary>
        /// <param name="info"><see cref="SerializationInfo"/> that contains the information.</param>
        /// <param name="context"><see cref="StreamingContext"/>.</param>
        protected Settings(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }
#endif

        public static Settings LoadDefault()
        {
            try
            {
                if (File.Exists(ConfigFileName))
                {
                    _instance = Load(ConfigFileName, SerializationMode.Xml);
                }
                else
                {
                    _instance = new Settings();
                }
            }
            catch (Exception)
            {
                _instance = new Settings();
            }

            return _instance;
        }

        public void Save()
        {
            this.Save(ConfigFileName, SerializationMode.Xml);
        }

        #endregion

        #region Properties
        // TODO: Define your custom properties here using the dataprop code snippet
        /// <summary>
        /// 按南充模式命名图片文件.
        /// </summary>
        public bool IsNanChongNamingSchema
        {
            get { return GetValue<bool>(IsNanChongNamingSchemaProperty); }
            set { SetValue(IsNanChongNamingSchemaProperty, value); }
        }

        /// <summary>
        /// Register the ListenPort property so it is known in the class.   
        /// </summary>
        public static readonly PropertyData IsNanChongNamingSchemaProperty = RegisterProperty("IsNanChongNamingSchema", typeof(bool), false);


        /// <summary>
        /// 本地数据接收监听端口.
        /// </summary>
        public bool SaveImageByDay
        {
            get { return GetValue<bool>(SaveImageByDayProperty); }
            set { SetValue(SaveImageByDayProperty, value); }
        }

        /// <summary>
        /// Register the ListenPort property so it is known in the class.   
        /// </summary>
        public static readonly PropertyData SaveImageByDayProperty = RegisterProperty("SaveImageByDay", typeof(bool), false);

        /// <summary>
        /// 本地数据接收监听端口.
        /// </summary>
        public int MaxImageFileSize
        {
            get { return GetValue<int>(MaxImageFileSizeProperty); }
            set { SetValue(MaxImageFileSizeProperty, value); }
        }

        /// <summary>
        /// Register the ListenPort property so it is known in the class.   
        /// </summary>
        public static readonly PropertyData MaxImageFileSizeProperty = RegisterProperty("MaxImageFileSize", typeof(int), 290);

        /// <summary>
        /// 本地数据接收监听端口.
        /// </summary>
        public bool CompressImage
        {
            get { return GetValue<bool>(CompressImageProperty); }
            set { SetValue(CompressImageProperty, value); }
        }

        /// <summary>
        /// Register the ListenPort property so it is known in the class.   
        /// </summary>
        public static readonly PropertyData CompressImageProperty = RegisterProperty("CompressImage", typeof(bool), true);


        /// <summary>
        /// 本地数据接收监听端口.
        /// </summary>
        public int ListenPort
        {
            get { return GetValue<int>(ListenPortProperty); }
            set { SetValue(ListenPortProperty, value); }
        }

        /// <summary>
        /// Register the ListenPort property so it is known in the class.   
        /// </summary>
        public static readonly PropertyData ListenPortProperty = RegisterProperty("ListenPort", typeof(int), 10000);

        /// <summary>
        /// 数据上传录入员.
        /// </summary>
        public string UploadLry
        {
            get { return GetValue<string>(UploadLryProperty); }
            set { SetValue(UploadLryProperty, value); }
        }

        /// <summary>
        /// Register the UploadLry property so it is known in the class.
        /// </summary>
        public static readonly PropertyData UploadLryProperty = RegisterProperty("UploadLry", typeof(string), "zjtest");
        /// <summary>
        /// 上传单位编码.
        /// </summary>
        public string UploadDwbm
        {
            get { return GetValue<string>(UploadDwbmProperty); }
            set { SetValue(UploadDwbmProperty, value); }
        }

        /// <summary>
        /// Register the UploadDwbm property so it is known in the class.
        /// </summary>
        public static readonly PropertyData UploadDwbmProperty = RegisterProperty("UploadDwbm", typeof(string), "510623");
        /// <summary>
        /// 上传key.
        /// </summary>
        public string UploadKey
        {
            get { return GetValue<string>(UploadKeyProperty); }
            set { SetValue(UploadKeyProperty, value); }
        }

        /// <summary>
        /// Register the UploadKey property so it is known in the class.
        /// </summary>
        public static readonly PropertyData UploadKeyProperty = RegisterProperty("UploadKey", typeof(string), "WC056724Z1990819854K");
        /// <summary>
        /// Gets or sets the property value.
        /// </summary>
        public string WeiZhangDataUrl
        {
            get { return GetValue<string>(WeiZhangDataUrlProperty); }
            set { SetValue(WeiZhangDataUrlProperty, value); }
        }

        /// <summary>
        /// Register the WeiZhangDataUrl property so it is known in the class.
        /// </summary>
        public static readonly PropertyData WeiZhangDataUrlProperty = RegisterProperty("WeiZhangDataUrl", typeof(string), "http://10.66.72.25:8080/dydzjcWebService/services/dyService");
        /// <summary>
        /// Gets or sets the property value.
        /// </summary>
        public bool UploadWeiZhangData
        {
            get { return GetValue<bool>(UploadWeiZhangDataProperty); }
            set { SetValue(UploadWeiZhangDataProperty, value); }
        }

        /// <summary>
        /// Register the UploadWeiZhangData property so it is known in the class.
        /// </summary>
        public static readonly PropertyData UploadWeiZhangDataProperty = RegisterProperty("UploadWeiZhangData", typeof(bool), false);
        /// <summary>
        /// 违法视频保存天数.
        /// </summary>
        public int WeiFaDataKeepDays
        {
            get { return GetValue<int>(WeiFaDataKeepDaysProperty); }
            set { SetValue(WeiFaDataKeepDaysProperty, value); }
        }

        /// <summary>
        /// Register the WeiFaVideoKeepDays property so it is known in the class.
        /// </summary>
        public static readonly PropertyData WeiFaDataKeepDaysProperty = RegisterProperty("WeiFaDataKeepDays", typeof(int), 1460);
        /// <summary>
        /// 布控报警视频保存天数.
        /// </summary>
        public int BuKongDataKeepDays
        {
            get { return GetValue<int>(BuKongDataKeepDaysProperty); }
            set { SetValue(BuKongDataKeepDaysProperty, value); }
        }

        /// <summary>
        /// Register the BuKongVideoKeepDays property so it is known in the class.
        /// </summary>
        public static readonly PropertyData BuKongDataKeepDaysProperty = RegisterProperty("BuKongDataKeepDays", typeof(int), 1095);
        /// <summary>
        /// 视频保存设置.
        /// </summary>
        public int DataKeepDays
        {
            get { return GetValue<int>(DataKeepDaysProperty); }
            set { SetValue(DataKeepDaysProperty, value); }
        }

        /// <summary>
        /// Register the VideoKeepDays property so it is known in the class.
        /// </summary>
        public static readonly PropertyData DataKeepDaysProperty = RegisterProperty("DataKeepDays", typeof(int), 730);






        /// <summary>
        /// 违法视频保存天数.
        /// </summary>
        public int WeiFaImageKeepDays
        {
            get { return GetValue<int>(WeiFaImageKeepDaysProperty); }
            set { SetValue(WeiFaImageKeepDaysProperty, value); }
        }

        /// <summary>
        /// Register the WeiFaVideoKeepDays property so it is known in the class.
        /// </summary>
        public static readonly PropertyData WeiFaImageKeepDaysProperty = RegisterProperty("WeiFaImageKeepDays", typeof(int), 1095);
        /// <summary>
        /// 布控报警视频保存天数.
        /// </summary>
        public int BuKongImageKeepDays
        {
            get { return GetValue<int>(BuKongImageKeepDaysProperty); }
            set { SetValue(BuKongImageKeepDaysProperty, value); }
        }

        /// <summary>
        /// Register the BuKongVideoKeepDays property so it is known in the class.
        /// </summary>
        public static readonly PropertyData BuKongImageKeepDaysProperty = RegisterProperty("BuKongImageKeepDays", typeof(int), 730);
        /// <summary>
        /// 视频保存设置.
        /// </summary>
        public int ImageKeepDays
        {
            get { return GetValue<int>(ImageKeepDaysProperty); }
            set { SetValue(ImageKeepDaysProperty, value); }
        }

        /// <summary>
        /// Register the VideoKeepDays property so it is known in the class.
        /// </summary>
        public static readonly PropertyData ImageKeepDaysProperty = RegisterProperty("ImageKeepDays", typeof(int), 365);





        /// <summary>
        /// 违法视频保存天数.
        /// </summary>
        public int WeiFaVideoKeepDays
        {
            get { return GetValue<int>(WeiFaVideoKeepDaysProperty); }
            set { SetValue(WeiFaVideoKeepDaysProperty, value); }
        }

        /// <summary>
        /// Register the WeiFaVideoKeepDays property so it is known in the class.
        /// </summary>
        public static readonly PropertyData WeiFaVideoKeepDaysProperty = RegisterProperty("WeiFaVideoKeepDays", typeof(int), 730);
        /// <summary>
        /// 布控报警视频保存天数.
        /// </summary>
        public int BuKongVideoKeepDays
        {
            get { return GetValue<int>(BuKongVideoKeepDaysProperty); }
            set { SetValue(BuKongVideoKeepDaysProperty, value); }
        }

        /// <summary>
        /// Register the BuKongVideoKeepDays property so it is known in the class.
        /// </summary>
        public static readonly PropertyData BuKongVideoKeepDaysProperty = RegisterProperty("BuKongVideoKeepDays", typeof(int), 365);
        /// <summary>
        /// 视频保存设置.
        /// </summary>
        public int VideoKeepDays
        {
            get { return GetValue<int>(VideoKeepDaysProperty); }
            set { SetValue(VideoKeepDaysProperty, value); }
        }

        /// <summary>
        /// Register the VideoKeepDays property so it is known in the class.
        /// </summary>
        public static readonly PropertyData VideoKeepDaysProperty = RegisterProperty("VideoKeepDays", typeof(int), 200);





        /// <summary>
        /// delete outdated data.
        /// </summary>
        public bool AutoDelOutdateData
        {
            get { return GetValue<bool>(AutoDelOutdateDataProperty); }
            set { SetValue(AutoDelOutdateDataProperty, value); }
        }

        /// <summary>
        /// Register the AutoDelOutdateData property so it is known in the class.
        /// </summary>
        public static readonly PropertyData AutoDelOutdateDataProperty = RegisterProperty("AutoDelOutdateData", typeof(bool), false);
        /// <summary>
        /// remote db server name.
        /// </summary>
        public string RemoteDbServer
        {
            get { return GetValue<string>(RemoteDbServerProperty); }
            set { SetValue(RemoteDbServerProperty, value); }
        }

        /// <summary>
        /// Register the RemoteDbServer property so it is known in the class.
        /// </summary>
        public static readonly PropertyData RemoteDbServerProperty = RegisterProperty("RemoteDbServer", typeof(string), "");
        /// <summary>
        /// remote db password.
        /// </summary>
        public string RemoteDbPassWord
        {
            get { return GetValue<string>(RemoteDbPassWordProperty); }
            set { SetValue(RemoteDbPassWordProperty, value); }
        }

        /// <summary>
        /// Register the RemoteDbPassWord property so it is known in the class.
        /// </summary>
        public static readonly PropertyData RemoteDbPassWordProperty = RegisterProperty("RemoteDbPassWord", typeof(string), "");
        /// <summary>
        /// remote db username.
        /// </summary>
        public string RemoteDbUserName
        {
            get { return GetValue<string>(RemoteDbUserNameProperty); }
            set { SetValue(RemoteDbUserNameProperty, value); }
        }

        /// <summary>
        /// Register the RemoteDbUserName property so it is known in the class.
        /// </summary>
        public static readonly PropertyData RemoteDbUserNameProperty = RegisterProperty("RemoteDbUserName", typeof(string), "");
        /// <summary>
        /// save to remote database.
        /// </summary>
        public bool Save2RemoteDb
        {
            get { return GetValue<bool>(Save2RemoteDbProperty); }
            set { SetValue(Save2RemoteDbProperty, value); }
        }

        /// <summary>
        /// Register the SaveToRemoteDb property so it is known in the class.
        /// </summary>
        public static readonly PropertyData Save2RemoteDbProperty = RegisterProperty("Save2RemoteDb", typeof(bool), "");

        /// <summary>
        /// 是否使用数据库.
        /// </summary>
        public bool Save2Db
        {
            get { return GetValue<bool>(Save2DbProperty); }
            set { SetValue(Save2DbProperty, value); }
        }

        /// <summary>
        /// Register the UseDb property so it is known in the class.
        /// </summary>
        public static readonly PropertyData Save2DbProperty = RegisterProperty("Save2Db", typeof(bool), false);

        /// <summary>
        /// database pass word.
        /// </summary>
        public string DbPassWord
        {
            get { return GetValue<string>(DbPassWordProperty); }
            set { SetValue(DbPassWordProperty, value); }
        }

        /// <summary>
        /// Register the DbPassWord property so it is known in the class.
        /// </summary>
        public static readonly PropertyData DbPassWordProperty = RegisterProperty("DbPassWord", typeof(string), "");
        /// <summary>
        /// database user name.
        /// </summary>
        public string DbUserName
        {
            get { return GetValue<string>(DbUserNameProperty); }
            set { SetValue(DbUserNameProperty, value); }
        }

        /// <summary>
        /// Register the DbUserName property so it is known in the class.
        /// </summary>
        public static readonly PropertyData DbUserNameProperty = RegisterProperty("DbUserName", typeof(string), "");

        /// <summary>
        /// database server.
        /// </summary>
        public string DbServer
        {
            get { return GetValue<string>(DbServerProperty); }
            set { SetValue(DbServerProperty, value); }
        }

        /// <summary>
        /// Register the DbServer property so it is known in the class.
        /// </summary>
        public static readonly PropertyData DbServerProperty = RegisterProperty("DbServer", typeof(string), "");



        /// <summary>
        /// Directory to save images to.
        /// </summary>
        public String TargetDirectory
        {
            get { return GetValue<String>(TargetDirectoryProperty); }
            set { SetValue(TargetDirectoryProperty, value); }
        }

        /// <summary>
        /// Register the TargetDirectory property so it is known in the class.
        /// </summary>
        public static readonly PropertyData TargetDirectoryProperty = RegisterProperty("TargetDirectory", typeof(String), string.Empty);
        #endregion

        #region Methods


        /// <summary>
        /// Validates the fields.
        /// </summary>
        protected override void OnValidatingFields()
        {
            //if (string.IsNullOrEmpty(TargetDirectory))
            //{
            //    var result = new FieldValidationResult("TargetDirectory", ValidationResultType.Error, "图片保存路径为空");
            //    SetFieldValidationResult(result);
            //}
            //else if (!Directory.Exists(TargetDirectory))
            //{
            //    var result = new FieldValidationResult("TargetDirectory", ValidationResultType.Error, "图片保存路径不存在");
            //    SetFieldValidationResult(result);
            //}

            if (Save2Db)
            {
                //检查数据库配置
                if (string.IsNullOrEmpty(DbServer))
                {
                    var r = new FieldValidationResult("DbServer", ValidationResultType.Error, "数据库服务器不能为空");
                    SetFieldValidationResult(r);
                }

                if (string.IsNullOrEmpty(DbUserName))
                {
                    var r = new FieldValidationResult("DbUserName", ValidationResultType.Error, "数据库用户名为空");
                    SetFieldValidationResult(r);
                }

                if (string.IsNullOrEmpty(DbPassWord))
                {
                    var r = new FieldValidationResult("DbPassWord", ValidationResultType.Error, "数据库密码为空");
                    SetFieldValidationResult(r);
                }
            }

            if (Save2RemoteDb)
            {
                //检查数据库配置
                if (string.IsNullOrEmpty(RemoteDbServer))
                {
                    var r = new FieldValidationResult("RemoteDbServer", ValidationResultType.Error, "远程数据库服务器不能为空");
                    SetFieldValidationResult(r);
                }

                if (string.IsNullOrEmpty(RemoteDbUserName))
                {
                    var r = new FieldValidationResult("RemoteDbUserName", ValidationResultType.Error, "远程数据库用户名为空");
                    SetFieldValidationResult(r);
                }

                if (string.IsNullOrEmpty(RemoteDbPassWord))
                {
                    var r = new FieldValidationResult("RemoteDbPassWord", ValidationResultType.Error, "远程数据库密码为空");
                    SetFieldValidationResult(r);
                }
            }

            if (AutoDelOutdateData)
            {
                //if (KeepDataOfDays <= 0)
                //{
                //    var r = new FieldValidationResult("KeepDataOfDays", ValidationResultType.Error, "数据保存天数不能为负数或者0");
                //    SetFieldValidationResult(r);
                //}
            }

            if (UploadWeiZhangData)
            {
                if (string.IsNullOrEmpty(WeiZhangDataUrl))
                {
                    var r = new FieldValidationResult("WeiZhangDataUrl", ValidationResultType.Error, "违章数据上传url不能为空");
                    SetFieldValidationResult(r);
                }

                if (string.IsNullOrEmpty(UploadKey))
                {
                    var r = new FieldValidationResult("UploadKey", ValidationResultType.Error, "违章数据上传序列号不能为空");
                    SetFieldValidationResult(r);
                }

                if (string.IsNullOrEmpty(UploadDwbm))
                {
                    var r = new FieldValidationResult("UploadDwbm", ValidationResultType.Error, "违章数据上传单位编码不能为空");
                    SetFieldValidationResult(r);
                }

                if (string.IsNullOrEmpty(UploadLry))
                {
                    var r = new FieldValidationResult("UploadLry", ValidationResultType.Error, "违章数据上传录入账号不能为空");
                    SetFieldValidationResult(r);
                }
            }

            if (CompressImage)
            {
                if (MaxImageFileSize <= 0)
                {
                    var r = new FieldValidationResult("MaxImageFileSize", ValidationResultType.Error, "图片文件大小小于等于0");
                    SetFieldValidationResult(r);
                }
                else if (MaxImageFileSize <= 100)
                {
                    var r = new FieldValidationResult("MaxImageFileSize", ValidationResultType.Warning, "图片文件大小可能过小");
                    SetFieldValidationResult(r);
                }
            }

        }



        /// <summary>
        /// Validates the business rules.
        /// </summary>
        protected override void OnValidatingBusinessRules()
        {
            // TODO: Implement any business rules of this object. Simply set any error by using the SetBusinessRuleError method
            //try
            //{
            //    var conn = OracleConnectionProvider.GetConnectionString(DbServer, DbUserName, DbPassWord);
            //    XpoDefault.GetDataLayer(conn, AutoCreateOption.None);
            //}
            //catch (Exception)
            //{
            //    var r = new BusinessRuleValidationResult(ValidationResultType.Error, "数据库配置错误，无法连接数据库");
            //    SetBusinessRuleValidationResult(r);
            //}

            if (UploadWeiZhangData)
            {
                if (string.IsNullOrEmpty(DbServer) || string.IsNullOrEmpty(DbUserName) || string.IsNullOrEmpty(DbPassWord))
                {
                    var r = new BusinessRuleValidationResult(ValidationResultType.Error, "违章数据上传功能要求本地数据库配置正确");
                    SetBusinessRuleValidationResult(r);
                }
            }
        }
        #endregion

    }
}
